using System;
using System.Buffers;
using UnityEngine.UIElements;

namespace M13.Utility
{
    public class ByteReader
    {
        int _i;

        public void SetReader(int index) { _i = index; }

        public void ResetReader() { _i = 0; }

        public byte ReadByte(byte[] scrArray)
        {
            return scrArray[_i++];
        }

        /// <summary>
        /// ���ֽ������ж�ȡ�����ֽ�����
        /// </summary>
        /// <param name="scrArray">Դ��������</param>
        /// <param name="length">Ҫ��ȡ�����ݳ���</param>
        /// <returns></returns>
        public byte[] ReadBytes(byte[] scrArray, int length)
        {
            byte[] bytes = new byte[length];
            Buffer.BlockCopy(scrArray, _i, bytes, 0, length);
            return bytes;
        }

        /// <summary>
        /// ���ֽ������ж�ȡ�����ֽ�����
        /// </summary>
        /// <param name="scrArray">Դ��������</param>
        /// <param name="startOffset">��ʼ������ƫ����</param>
        /// <param name="length">Ҫ��ȡ�ĳ���</param>
        /// <returns></returns>
        public byte[] ReadBytes(byte[] scrArray, int startOffset, int length)
        {
            byte[] bytes = new byte[length];
            Buffer.BlockCopy(scrArray, startOffset, bytes, 0, length);
            return bytes;

        }

        /// <summary>
        /// ��ȡ�������ݣ���������д�����������ʹ����ɺ���Ҫ��������
        /// </summary>
        /// <param name="scrArray">Դ��������</param>
        /// <param name="length">Ҫ��ȡ�ĳ���</param>
        /// <param name="bytes"></param>
        public void ReadBytesWithPool(byte[] scrArray, int length, out byte[] bytes)
        {
            bytes = ArrayPool<byte>.Shared.Rent(length);
            Buffer.BlockCopy(scrArray, _i, bytes, 0, length);           
        }

        /// <summary>
        /// ��ȡ�������ݣ���������д�����������ʹ����ɺ���Ҫ��������
        /// </summary>
        /// <param name="scrArray">Դ��������</param>
        /// <param name="startOffset">��ʼ������ƫ����</param>
        /// <param name="length">Ҫ��ȡ�ĳ���</param>
        /// <param name="bytes"></param>
        public void ReadBytesWithPool(byte[] scrArray,int startOffset, int length, out byte[] bytes)
        {
            bytes = ArrayPool<byte>.Shared.Rent(length);
            Buffer.BlockCopy(scrArray, startOffset, bytes, 0, length);
        }

        /// <summary>
        /// ��ȡ�������ݣ���������д�����������ʹ����ɺ���Ҫ��������
        /// </summary>
        /// <param name="scrArray">Դ��������</param>
        /// <param name="length">Ҫ��ȡ�ĳ���</param>
        public byte[] ReadBytesWithPool(byte[] scrArray, int length)
        {
            byte[] bytes = ArrayPool<byte>.Shared.Rent(length);
            Buffer.BlockCopy(scrArray, _i, bytes, 0, length);
            return bytes;
        }

        public short ReadShort(byte[] scrArray)
        {
            short r = BitConverter.ToInt16(scrArray, _i);
            _i += sizeof(short);
            return r;
        }

        public int ReadInt(byte[] scrArray)
        {
            int r = BitConverter.ToInt32(scrArray, _i);
            _i += sizeof(int);
            return r;
        }

        public int[] ReadIntArray(byte[] scrArray, int intsLength)
        {
            int[] ints = new int[intsLength];
            for (int j = 0; j < intsLength; j++)
            {
                ints[j] = ReadInt(scrArray);
            }
            return ints;
        }

        public int[] ReadIntArrayWithPool(byte[] scrArray, int intsLength)
        {
            int[] ints = ArrayPool<int>.Shared.Rent(intsLength);
            for (int j = 0; j < intsLength; j++)
            {
                ints[j] = ReadInt(scrArray);
            }
            return ints;
        }

        public long ReadLong(byte[] scrArray)
        {
            long r = BitConverter.ToInt64(scrArray, _i);
            _i += sizeof(long);
            return r;
        }

        public float ReadFloat(byte[] scrArray)
        {
            float r = BitConverter.ToSingle(scrArray, _i);
            _i += sizeof(float);
            return r;
        }

        public float[] ReadFloatArray(byte[] scrArray, int floatsLength)
        {
            float[] floats = new float[floatsLength];
            for (int j = 0; j < floatsLength; j++)
            {
                floats[j] = ReadFloat(scrArray);
            }
            return floats;
        }

        public float[] ReadFloatArrayWithPool(byte[] scrArray, int floatsLength)
        {
            float[] floats = ArrayPool<float>.Shared.Rent(floatsLength);
            for (int j = 0; j < floatsLength; j++)
            {
                floats[j] = ReadFloat(scrArray);
            }
            return floats;
        }

        public double ReadDouble(byte[] scrArray)
        {
            double r = BitConverter.ToDouble(scrArray, _i);
            _i += sizeof(double);
            return r;
        }
    }
}